package cn.org.xiaosheng.test;

import com.google.common.cache.*;

import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class GuavaCacheExample {



    /**
     * 在这个例子中，我们首先使用CacheBuilder创建了一个LoadingCache，并设置了一些参数，如最大容量、写后过期时间、开启统计信息等。然后我们定义了CacheLoader来加载缓存数据。
     * 在main方法中，我们首先尝试从缓存中获取数据，但因为此时缓存是空的，所以会调用CacheLoader.load方法来加载数据；
     * 然后我们再次尝试获取数据，此时数据已经在缓存中，所以可以直接获取到，不需要再次加载；接着我们打印了一些缓存的统计信息，如命中率等；最后我们显式地清除了缓存。
     */
    private static final LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存的最大容量
            .expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存在写入10分钟后失效
            .recordStats() // 开启缓存统计
            .build(new CacheLoader<String, String>() { // 设置缓存的加载方式
                @Override
                public String load(String key) {
                    return getDataFromDatabase(key);
                }

                @Override
                public Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {
                    return super.loadAll(keys);
                }
            });

    private static String getDataFromDatabase(String key) {
        // 这里是模拟从数据库中加载数据
        return "Data for " + key;
    }

    public static void main(String[] args) throws ExecutionException {
        // 在缓存中取值，如果缓存中没有对应的key，则会调用CacheLoader.load方法加载缓存数据
        String value = cache.get("key1");
        System.out.println("Initial cache value: " + value);

        // 再次在缓存中取值，由于缓存中已经存在，所以不会再次调用CacheLoader.load方法
        value = cache.get("key1");
        System.out.println("Cached value: " + value);

        // 打印缓存的命中率等统计信息
        System.out.println("Cache stats: " + cache.stats());

        // 显式地清除缓存
        cache.invalidate("key1");
    }
}
